<?php

namespace App\Http\Controllers;

use App\Http\Controllers\LibApi\LibApiController;
use App\Models\SystemInfo;
use App\Models\UserInfo;
use App\Models\UserLibraryInfo;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use SebastianBergmann\CodeUnit\FunctionUnit;

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;



    //接收全部请求变量
    public $request = null;
    public function __construct()
    {
        $this->request = request();
    }



    /**
     * 获取请求域名
     */
    public function getHostUrl()
    {
        return $this->request->getScheme() . "://" . $this->request->getHttpHost() . $this->request->getBasePath(); //最后不带斜线
    }
    /**
     * 获取请求域名
     */
    public function getDomainName()
    {
        return $this->request->getScheme() . "://" . $this->request->getHttpHost(); //最后不带斜线
    }

    /**
     * 获取图片地址
     */
    public function getImgAddrUrl()
    {
        return $this->getHostUrl() . '/uploads/'; //最后带斜线
    }

    /**
     * 获取图书馆接口对象
     */
    public function getLibApiObj()
    {
        return new LibApiController();
    }

    /**
     * 删除图片
     *
     * @param [type] $file  字符串删除单个  数组删除多个  只支持一维数组
     * @return void
     */
    public function deleteFile($file)
    {
        $path = public_path('uploads');
        delete_file_or_dir($file, $path);
    }

    /**
     * 学历信息
     */
    public static function educationName()
    {
        $education = [
            '小学',
            '初中',
            '高中',
            '专科',
            '本科',
            '硕士',
            '博士',
            '其他',
        ];

        return $education;
    }

    /**
     * 内置的文化配送类型标签
     */
    public function definedReservationTag()
    {
        $reservationTag = [
            '音乐',
            '舞蹈',
            '美术',
            '书法',
            '摄影',
            '文学',
            '曲艺',
            '戏剧',
            '展览',
            '讲座',
            '物品',
            '其他',
        ];

        return $reservationTag;
    }


    /**
     * 返回api设置
     */
    public  function returnApi($code, $msg, $type = false, $data = null)
    {
        $result = ['code' => $code, 'msg'  => $msg];
        if ($type) $result['content'] = $data;
        return $result;
    }

    /**
     * 处理分页数据，返回必要字段即可
     */
    public function disPageData($data)
    {
        $datas = [];
        $datas['data'] = $data['data'];
        $datas['total'] = $data['total'];
        $datas['per_page'] = $data['per_page'];
        $datas['current_page'] = $data['current_page'];
        $datas['last_page'] = $data['last_page'];
        return $datas;
    }

    /**
     * 处理数据，把数据放到同一级
     * @param $data
     * @param $oneField  一级的 key
     * @param $towField  二级的 key，需要提到第一级的数据  key为健名  值为别名 
     */
    public function disDataSameLevel($data, $oneField, $towField = [])
    {
        if (array_key_exists($oneField, $data)) {
            //一维数组的处理方式
            foreach ($towField as $k => $v) {
                if (is_numeric($k)) {
                    $data[$v] =  isset($data[$oneField][$v]) ? $data[$oneField][$v] : '';
                } else {
                    $data[$v] =  isset($data[$oneField][$k]) ? $data[$oneField][$k] : '';
                }
            }
            unset($data[$oneField]);
        } else {
            //二维数组的处理方式
            foreach ($data as $key => &$val) {
                if (is_numeric($val)) {
                    return $data; //一维数组
                }
                foreach ($towField as $k => $v) {
                    if (is_numeric($k)) {
                        $data[$key][$v] =  !empty($val[$oneField][$v]) ?  $val[$oneField][$v] : '';
                    } else {
                        $data[$key][$v] =  !empty($val[$oneField]) ? $val[$oneField][$k] : '';
                    }
                }
                unset($val[$oneField]);
            }
        }
        return $data;
    }


    /**
     * 高德地图，根据经纬度获取地址
     * @param $lon
     * @param $lat
     * @return mixed
     * @throws \think\exception\PDOException
     */
    public function getAddressByLonLat($lon, $lat)
    {
        $gaode_key = config('other.gaode_key'); //获得高的地图的key
        $url = "http://restapi.amap.com/v3/geocode/regeo?output=xml&location=" . $lon . ',' . $lat . "&key=" . $gaode_key . "&radius=1000";
        $addrInfo = request_url($url);
        //判断是否成功获得经纬度
        $addrInfo = simplexml_load_string($addrInfo); //把xml转换为对象
        $addrInfo = object_array($addrInfo); //把对象转换为数组
        if ($addrInfo['info'] == 'OK') {
            $data['province'] = $addrInfo['regeocode']['addressComponent']['province'];
            $data['city'] = $addrInfo['regeocode']['addressComponent']['city'];
            $data['district'] = $addrInfo['regeocode']['addressComponent']['district'];

            $street_name = empty($addrInfo['regeocode']['addressComponent']['neighborhood']['name']) ? '' : $addrInfo['regeocode']['addressComponent']['neighborhood']['name'];
            $township = empty($addrInfo['regeocode']['addressComponent']['township']) ? '' : $addrInfo['regeocode']['addressComponent']['township'];

            $data['remark'] = $street_name ? $township . $street_name : $township;
        } else {
            return '地址获取失败，请检查经纬度是否正确';
        }
        return $data;
    }

    /**
     * 高德地图，根据地址获取经纬度
     * @param $address
     * @return mixed
     * @throws \think\exception\PDOException
     */
    public function getLonLatByAddress($address)
    {
        //获得所填地址的经纬度
        $gaode_key = config('other.gaode_key'); //获得高的地图的key
        $url = "http://restapi.amap.com/v3/geocode/geo?key=" . $gaode_key . "&address=" . $address;
        $addrInfo = request_url($url);
        //判断是否成功获得经纬度
        $addrInfo = json_decode($addrInfo, true); //把json转换为数组

        //如果为1表示成功
        if ($addrInfo['status'] == '1') {
            list($data['lon'], $data['lat']) = explode(",", $addrInfo['geocodes'][0]['location']);
        } else {
            return '经纬度获取失败，请检查地址是否正确';
        }
        return $data;
    }


    /**
     * 根据用户id，判断积分是否满足要求
     */
    public function checkScoreByUserId($user_id, $type)
    {
        //判断读者证号密码是否正确 和是否绑定读者证
        $userLibraryInfo = new UserLibraryInfo();
        $account_lib_info = $userLibraryInfo->checkAccountPwdIsNormal($user_id);
        if (is_string($account_lib_info)) {
            return false;
        }

        $is_score = $this->checkScore($account_lib_info, $type);
        return $is_score ? true : false;
    }

    /**
     * 添加系统消息
     * @param $user_id  用户id
     * @param $type   类型  1.【绑定和首次绑定读者证增加积分】 2.【意见反馈回复】  3【活动报名】 4、【取消活动报名】  5.【活动审核状态】 6【活动违规与取消违规】 
     *                      7 【商品兑换】8、【取消商品兑换】 9、【取消商品兑换订单】   10【用户签到】         
     *                      11【邀请用户注册获取积分】 12【邀请用户注册后首次绑定读者证】   
     *                      13【兑换商品领取成功通知、兑换商品发货成功通知】  14【活动签到】
     *                      15【线上大赛上传作品成功】16【线上大赛作品撤销、删除】  17【线上大赛作品审核通过、审核未通过】 
     *                      18【志愿者提交成功】19【志愿者撤销成功】20【志愿者审核通过、审核不通过】21【参与问卷调查】
     *                      22【缴纳欠费消息】 23.【景点打卡作品提交、修改成功】 24.【景点打卡作品撤销、删除成功】   
     *                      25【在线办证缴纳成功消息】26【在线办证押金退回消息】 
     * 
     *                      27.【商品支付成功提醒】 28.【商品退款成功提醒】
     * 
     *                      29.【系统推送--服务提醒通知】  30.【预约成功通知】  31.【预约取消成功通知】 32.【预约审核通过、审核未通过通知】  33.【预约预约违规、取消违规通知】
     *                      34.【场馆预约失效通知】   35.【在线荐购审核通知】  36【新书采购提交成功】 37【馆藏书采购提交成功】 38【馆藏书续借成功】
     *                      39【新书采购审核】  40【新书发货审核】 41【馆藏书采购审核】42【馆藏书发货审核】 43【采购书籍归还】
     * 
     *                      44【新书采购退款】 45【馆藏书采购退款】 46【扫码借书成功】  47【扫码还书成功】 48【场馆预约签到、签退】 49【管理员取消场馆预约】 50【借还书积分消息】
     *                      51【空间预约签到签退】 52.【空间预约违规、取消违规通知】  53.【空间预约失效通知】 54.【空间预约成功通知】 55.【空间预约取消成功通知】 
     *                      56【预约审核通过、审核未通过通知】  57【管理员取消空间预约】 58.【景点打卡作品审核通过、审核未通过通知】  59.【景点打卡作品违规、取消违规通知】  
     *                      60【线上大赛作品违规、取消违规通知】  61【邮借还书提交成功通知】 62【线下借阅采购成功通知】 
     *
     * @param $con_id  对应消息记录id
     *                     1.【系统详细详情】  2.【意见反馈详情】   3【我的活动报名详情】   4.【活动报名详情】 5.【活动报名详情】 6【系统消息详情】   
     *                     7 【商品兑换详情】   8【系统消息详情】   9【系统消息详情】    10【系统消息详情】
     *                     11【兑换商品详情】 12【系统消息详情】   13【商品兑换详情】
     *                     14【活动详情】  15【线上大赛作品详情】 16【线上大赛作品详情】  17【线上大赛作品详情】 
     *                     18【志愿者详情】  19【志愿者详情】 20【志愿者详情】   21.【系统详细详情】22.【系统详细详情】
     *                     23.【景点打卡作品详情】 24.【景点打卡作品详情】   25.【在线办证订单详情】 26.【在线办证订单详情】
     * 
     *                     27.【商品订单详情】 28.【商品订单详情】
     * 
     *                     29【系统消息详情】  30【预约详情】 31【预约详情】 32【预约详情】 33【预约详情】 34【预约详情】
     *                     35【在线荐购书籍详情】 36【新书采购订单详情】 37【馆藏书采购订单详情】 38【系统消息详情】
     *                     39【新书采购订单详情】40【新书采购订单详情】 41【馆藏书采购订单详情】 42【馆藏书采购订单详情】 43【系统消息详情】 
     * 
     *                     44【新书采购订单详情】 45【馆藏书采购订单详情】 46【系统详细详情】  47【系统详细详情】 48【我的预约列表】   49【系统消息详情】  50【系统消息详情】
     *                     51【空间预约我的预约列表】 52【空间预约我的预约列表】53【空间预约我的预约列表】 54.【空间预约我的预约列表】  55.【空间预约我的预约列表】
     *                     56.【空间预约我的预约列表】 57.【空间预约我的预约列表】 58.【景点打卡作品详情】    59.【景点打卡作品详情】  60.【线上大赛作品详情】
     *                     61【邮借还书中的列表】 62【图书到家借阅中的列表】 
     * @param $intro   系统消息简介
     * @param $title   系统消息标题
     * @param $time    时间
     */
    public function systemAdd($title, $user_id, $account_id, $type, $con_id, $intro, $time = null)
    {
        if (empty($account_id)) {
            $userInfoModelObj = new UserInfo();
            $account_id = $userInfoModelObj->getAccountId($user_id);
        }
        $systemObj = new SystemInfo();
        $systemObj->title = $title;
        $systemObj->user_id = $user_id;
        $systemObj->account_id = !empty($account_id) ? $account_id : 0;
        $systemObj->type = $type;
        $systemObj->con_id = !empty($con_id) ? $con_id : 0;
        $systemObj->intro = $intro;
        $systemObj->create_time = $time ? $time : date('Y-m-d H:i:s');
        $systemObj->save();

        return $systemObj->id; //返回系统消息ID

        //下面推送消息
    }


    /**
     * 时间转换为上午 和下午
     * @param $datetime  时间   比如  2020-08-28 09:00:00 转换为  2020-08-29 上午 09:00:00
     */
    public function switchTime($datetime)
    {
        $date = substr($datetime, 0, 10);
        $date = str_replace('-', '.', $date);
        $time = substr($datetime, 11);
        $stage = substr($datetime, 11, 2);
        $stage = $stage >= 12 ? '下午' : '上午';
        return [$date, $time, $stage];
    }


    /**
     * 验证签名是否正确
     * @param timestamp  时间戳  13位
     * @param sign  签名  token 拼接 sign_key 拼接 时间戳  然后  md5后值 在全部转大写的值
     * @param token  用户guid
     */
    public function verifySignature($timestamp, $token, $sign)
    {
        //判断时间戳是否有效 1 分钟有效期
        if ($timestamp < strtotime('-1 min') . '000') {
            return false;
        }
        $sign_key = config('other.sign_key');
        $new_sign = strtoupper(md5($token . $sign_key . $timestamp));
        if ($sign != $new_sign) {
            return false;
        }
        return true;
    }


    /**
     * 获取中图分类法类型
     * $param letter 首字母
     */
    public static function getTypeBigId($letter)
    {
        if (empty($letter)) {
            return null;
        }
        $letter = strtoupper(substr($letter, 0, 1));
        if (!in_array($letter, ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'X', 'Z'])) {
            return 0;
        }
        $pattern = [
            'A' => 2,
            'B' => 141,
            'C' => 896,
            'D' => 1110,
            'E' => 2235,
            'F' => 2666,
            'G' => 4237,
            'H' => 5668,
            'I' => 6191,
            'J' => 6495,
            'K' => 7464,
            'N' => 9484,
            'O' => 9580,
            'P' => 11634,
            'Q' => 13945,
            'R' => 17417,
            'S' => 21152,
            'T' => 25844,
            'U' => 40585,
            'X' => 45419,
            'Z' => 45735,
        ];
        return $pattern[$letter];
    }

    /**
     * 图片移动到指定位置，并返回移动后的路径
     * @param temp_file 临时文件路径  图片上传后的路径  temp_merge/1681699905643cb4413e418.mp3
     * @param move_dir 移动后文件夹名
     */
    public function moveUploadedFile($temp_file, $move_dir)
    {
        $uploads_path = public_path('uploads');
        $file_addr = $uploads_path . '/' . $temp_file;
        $file_addr_pathinfo = pathinfo($file_addr);
        $move_file = $move_dir . '/' . date('Y-m-d') . '/' . uniqid() . '.' . $file_addr_pathinfo['extension'];

        if (!file_exists(dirname($uploads_path . '/' . $move_file))) {
            mkdir(dirname($uploads_path . '/' . $move_file), 0777, true);
        }

        //修改文件夹权限
        if (!chmod(dirname($uploads_path . '/' . $move_file), 0777)) {
            return false;
        }
        if (!chmod(dirname($file_addr), 0777)) {
            return false;
        }

        $res = copy($file_addr, $uploads_path . '/' . $move_file);
        if ($res) {
            @unlink($file_addr);
            return $move_file;
        }
        return false;
    }

    /**
     * 删除所有临时文件
     */
    public function delAllTempFile()
    {
        //删除临时文件下的文件
        $temp_dir = ['temp', 'temp_qr', 'temp_merge', 'temp_video', 'temp_audio'];
        foreach ($temp_dir as $val) {
            if ($val == 'temp_video' || $val == 'temp_audio') {
                $filedir = public_path('uploads') . '/' . $val . '/';
                $src_path_data = get_dir_content_list($filedir);
                if ($src_path_data) {
                    foreach ($src_path_data as $v) {
                        del_past_imgs($filedir . $v . '/', 7200); //删除过期图片
                    }
                }
            } else {
                $filedir = public_path('uploads') . '/' . $val . '/';
                del_past_imgs($filedir, 7200); //删除过期图片
            }
        }
    }

    /**
     * 获取填报参数（前台使用）
     * @param 需要的字段
     **/
    public function getRealInfoArray($real_info, $real_info_param, $field = null)
    {
        $new_real_info = [];
        if ($real_info) {
            $real_info = explode("|", $real_info);
            foreach ($real_info_param as $k => $v) {
                foreach ($real_info as $key => $val) {
                    if ($val == $v['id']) {
                        $new_real_info[] = $field ? $v[$field] : $v;
                        continue;
                    }
                }
            }
        }
        return $new_real_info;
    }


    /**
     * 根据isbn获取图片
     * @param isbn
     */
    public function getImgByIsbn($isbn, $data = [])
    {
        $url = 'https://www.usharego.com/readshareadmin/public/index/bookClusterApi/getBookinfo';
        $url .= '?isbn=' . $isbn . '&key=' . md5('resource_integration' . $isbn);

        if ($data) {
            $data['china_type_id'] = !empty($data['book_num']) ? $data['book_num'] : ''; //用requestUrl 发送数据是，null参数会自动过滤掉
        }
        $res = json_decode(request_url($url, $data, 10), true);
        //  dump($res);die;
        if (empty($res) || $res['code'] !== 200) {
            return false;
        }

        if (!empty($res['content']['thumb_img'])) {
            $end_img = explode('/', $res['content']['thumb_img']);
            $end_img = end($end_img);

            if ($end_img !== 'default_book_thumb.png') {
                //验证缩略图
                if (strpos($res['content']['thumb_img'], 'http') === false && strpos($res['content']['thumb_img'], 'https') === false) {
                    $img = 'https://www.usharego.com/Uploads/' . $res['content']['thumb_img'];
                } else {
                    $img = $res['content']['thumb_img'];
                }

                $img_exists = request_url($img);
                if ($img_exists && strpos($res['content']['thumb_img'], '404 Not Found') === false) {
                    return $img;
                }

                //验证正常图片
                if (strpos($res['content']['img'], 'http') === false && strpos($res['content']['img'], 'https') === false) {
                    $img = 'https://www.usharego.com/Uploads/' . $res['content']['img'];
                } else {
                    $img = $res['content']['img'];
                }
                $img_exists = request_url($img);
                if ($img_exists && strpos($res['content']['img'], '404 Not Found') === false) {
                    return $img;
                }
            }
        }
        return false;
    }

    /**
     * 数据加密后生成二维码
     * @param data 数组格式
     * @param $expire 有效期  单位分钟
     */
    public function dataEncryptCreateQr($data, $expire = '3')
    {
        $data['expire_time'] = date('Y-m-d H:i:s', strtotime("+$expire min"));
        $access_system_qr_secret_key = config('other.access_system_qr_secret_key');
        $access_system_qr_secret_key = substr($access_system_qr_secret_key, 0, 8);

        $data_encrypt = encrypt1($data, $access_system_qr_secret_key);
        $data_encrypt = 'CDBT' . $data_encrypt;

        $qrCodeObj = new QrCodeController();

        //生成二维码
        $qr_url = $qrCodeObj->setQr($data_encrypt);
        return $qr_url;
    }

    /**
     * 数据解密后生成二维码  
     * @param data 数组格式
     * @param $expire 有效期  单位分钟
     */
    public function dataDecrypt($data)
    {
        $data = str_replace('\\000026', '', $data);
        $prefix = substr($data, 0, 4);
        if ($prefix != 'CDBT') {
            return false;
        }
        $data = $prefix = substr($data, 4);
        $access_system_qr_secret_key = config('other.access_system_qr_secret_key');
        $access_system_qr_secret_key = substr($access_system_qr_secret_key, 0, 8);
        $data = decrypt1($data,  $access_system_qr_secret_key);     //decrypt 是 使用 的 内置的函数  但必须运行此命令 php artisan key:generate   因为自己写的生成的二维码简单些，所以使用自己写的方法
        return $data;
    }
}
